#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "queue.h"

int queue_init(queue_t **q, int size, int capacity)
{
	*q = malloc(sizeof(queue_t));
	if(NULL == *q) {
		return -1;
	}

	(*q)->data_start = malloc(capacity * size);
	if(NULL == (*q)->data_start) {
		return -1;
	}

	(*q)->tail = 0;
	(*q)->front = 0;
	(*q)->size = size;
	(*q)->capacity = capacity;
	
	return 0;
}

int queue_is_full(const queue_t *q)
{
	return (q->tail + 1) % q->capacity == q->front;
}

int queue_is_empty(const queue_t *q)
{
	return q->tail == q->front;
}

int queue_enq(queue_t *q, const void *data)
{
	if(queue_is_full(q)) {
		return -1;
	}

	memcpy((char *)q->data_start + q->tail * q->size, data, q->size);
	q->tail = (q->tail + 1) % q->capacity;

	return 0;
}

int queue_deq(queue_t *q, void *data)
{
	if(queue_is_empty(q)) {
		return -1;
	}
	
	memcpy(data, (char *)q->data_start + q->front * q->size, q->size);
	q->front = (q->front + 1) % q->capacity;

	return 0;
}

void queue_destroy(queue_t **q)
{
	free((*q)->data_start);
	(*q)->data_start = NULL;
	free(*q);
	*q = NULL;
}
